package me.zhengjie.controller.wcs;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import me.zhengjie.dao.*;
import me.zhengjie.enums.ConstantStatus;
import me.zhengjie.enums.InboundStatusEnum;
import me.zhengjie.network.MesNetworkRequest;
import me.zhengjie.server.*;
import me.zhengjie.utils.SnowIdUtil;
import me.zhengjie.vo.mes.ResponseResult;
import me.zhengjie.vo.wcs.ResponseTaskToWcsVo;
import me.zhengjie.vo.Result;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("wms/outbound/")
public class WCSController {

    @Resource
    private StoreLocalService storeLocalService;

    @Resource
    private StoreOutsideService storeOutsideService;

    @Resource
    private MergeTaskService mergeTaskService;

    @Resource
    private InventoryTaskService inventoryTaskService;

    @Resource
    private FreezeService freezeService;

//    @Resource
//    private OutInBoundRecordService recordService;

    @Resource
    private FreezeTaskRecordService freezeTaskRecordService;

    @Resource
    private ContainerMoveService containerMoveService;

    @Resource
    private ContainerService containerService;

    @Resource
    private MaterialService materialService;

    @Resource
    private DispositionService dispositionService;


    @RequestMapping(value = "pickPlace", method = RequestMethod.POST)
    @ResponseBody
    @Transactional(rollbackFor = Exception.class)
    public Result<?> storageCompletedUpdate(@RequestBody ResponseTaskToWcsVo responseTaskToWcsVo) {
        System.out.println("********: " + responseTaskToWcsVo);
        // 任务ID
        String taskId = responseTaskToWcsVo.getWmsTaskId();
        // 出库类型 1取货，2放货
        Integer type = responseTaskToWcsVo.getType();
        // 任务类型（判断是出库，冻结, 合箱, 盘点）
        String taskType = responseTaskToWcsVo.getTaskType();
        // 入庫，2出庫
        Integer boundType = responseTaskToWcsVo.getBoundType();
        // 是否回库
        Boolean isNest = responseTaskToWcsVo.getNest();
        // 载具编码
        String containerCode = responseTaskToWcsVo.getContainerCode();
        // 储位编码
        String storageId = responseTaskToWcsVo.getStorageCode();
        // 获取载具信息
        ContainerDao containerDao = containerService.findDataOne(containerCode);

        if (containerDao == null) {
            return Result.error("载具编码查询为空！");
        }
        // 获取载具位置
        String ContainerType = containerDao.getLocal();
        // 更新载具储位
        String updateType = ContainerType.equals(ConstantStatus.OutsideTheWarehouse)
                ? ConstantStatus.InsideTheWarehouse : ConstantStatus.OutsideTheWarehouse;
        // 物料信息
        List<MaterialDao> materialList = materialService
                .findDataDao(new MaterialDao().setContainerCode(containerCode));
        if (boundType == 2 && type.equals(1)) {
            // 库内取货 == 开始出库
            this.outboundPickTask(storageId, containerCode);
            // 合箱出库
            if (taskType != null && taskType.equals(ConstantStatus.Merge_OutBound_Type)) {
                this.mergeOutBoundTask(containerCode);
            }
            // 冻结出库
            if (taskType != null && taskType.equals(ConstantStatus.Freeze_OutBound_Type)) {
                this.freezeOutBoundTask(containerCode);
            }
            // 盘点出库
            if (taskType != null && taskType.equals(ConstantStatus.Stock_OutBound_Type)) {
                this.stockOutBoundTask(containerCode);
            }
        }
        if (boundType == 2 && type.equals(2)) {
            // 库内放货 == 完成出库
            this.inboundDropTask(containerCode, storageId, materialList);
            // 如果是冻结物料，需要解冻
        }


        if (boundType == 1 && type.equals(1)) {
            // 库外取货 == 开始入库
            this.inboundPickTask(storageId, containerCode);
            // 冻结开始回库
            if (taskType != null && taskType.equals(ConstantStatus.Freeze_RetBound_Type)) {
                // 需要删除物料信息
                freezeService.deleteByContainerCode(containerCode);
            }
        }
        if (boundType == 1 && type.equals(2)) {
            // 库外放货 == 完成入库
            this.outboundDropTask(responseTaskToWcsVo, materialList, updateType);
            // 冻结回库
            if (taskType != null && taskType.equals(ConstantStatus.Freeze_RetBound_Type)) {
                this.freezeReturnTask(containerCode);
            }
            // 合箱回库
            if (taskType != null && taskType.equals(ConstantStatus.Merge_RetBound_Type)) {
                this.mergeReturnTask(containerCode);
            }
            // 盘点回库
            if (taskType != null && taskType.equals(ConstantStatus.Stock_RetBound_Type)) {
                this.stockReturnTask(containerCode);
            }
        }
        return Result.success();
    }

    /**
     * 载具库外+放货=完成入库到库内储位
     *
     * @param wcsVo        wcsVo
     * @param materialList 物料信息
     */
    public void outboundDropTask(ResponseTaskToWcsVo wcsVo, List<MaterialDao> materialList,
                                 String updateType) {
        String storageId = wcsVo.getStorageCode();
        String containerCode = wcsVo.getContainerCode();
        Boolean isNest = wcsVo.getNest();

        // 获取旧库区与旧储位信息
        MaterialDao material = materialList.get(0);
        String oldWarehouse = material.getWarehouse();
        String oldStorageCode = material.getIssuePosition();
        // 获取库区信息
        String newWarehouse = storageId.split("-")[0];

        // 更新物料的储位位置
        materialService.updateDataByList(null, new MaterialDao()
                .setContainerCode(containerCode)
                .setWarehouse(newWarehouse)
                .setIssuePosition(storageId));

        // 回库需要嵌套
        if (isNest != null && isNest) {
            MesNetworkRequest.nestedReturnToLibraryRequest(materialList, containerCode);
        }

        // 修改库内储位状态, 设置载具编码
        StoreLocalDao storeLocalDao = new StoreLocalDao()
                .setId(storageId)
                .setContainerCode(containerCode)
                .setStatus(InboundStatusEnum.STORAGE_LOAD.status);
        storeLocalService.updateData(storeLocalDao);

        MaterialDao materialDao = materialService.findItemBarCodeByContainerCode(containerCode);
        // 获取载具上物料总重量
        Double materialWeight = materialService.countTotalMaterialWeight(containerCode);
        // 修改载具位置
        ContainerDao containerDao = new ContainerDao()
                .setId(containerCode)
                .setLocal(updateType)
                .setItemBarCode(materialDao.getItemBarCode())
                .setWeight(materialWeight);
        containerService.updateDataById(containerDao);
        // 发送同步入库消息
        MesNetworkRequest.InventorySynchronizationRequest(containerCode, oldStorageCode, oldWarehouse, storageId, newWarehouse);
    }

    /**
     * 载具库内+放货=完成出库到库外储位
     *
     * @param containerCode 载具编码
     * @param outStoreId    库外储位id
     * @param materialList  物料信息
     */
    public void inboundDropTask(String containerCode, String outStoreId, List<MaterialDao> materialList) {

        // 获取库区信息
        String newWarehouse = outStoreId.split("-")[0];
        // 更新物料的储位位置
        materialService.updateDataByList(null, new MaterialDao()
                .setContainerCode(containerCode)
                .setWarehouse(newWarehouse)
                .setIssuePosition(outStoreId));

        // 物料出库完成，需要解套
        MesNetworkRequest.outboundUnNestingRequest(containerCode, null, materialList);

        // 修改库外储位状态, 设置载具编码
        StoreOutsideDao storeOutsideDao = new StoreOutsideDao()
                .setId(outStoreId)
                .setContainerCode(containerCode)
                .setStatus(InboundStatusEnum.STORAGE_LOAD.status);
        storeOutsideService.updateData(storeOutsideDao);

        // 修改载具位置
        ContainerDao containerDao = new ContainerDao()
                .setId(containerCode)
                .setLocal(ConstantStatus.OutsideTheWarehouse);
        containerService.updateDataById(containerDao);
    }

    /**
     * 载具库外+取货=开始入库库内储位
     *
     * @param storageId 库内储位id
     */
    public void outboundPickTask(String storageId, String containerCode) {
        // 修改库内储位状态,更新载具编码为空
        StoreLocalDao storeLocalDao = new StoreLocalDao()
                .setId(storageId)
                .setStatus(InboundStatusEnum.STORAGE_FREE.status);
        storeLocalService.updateData(storeLocalDao);

        // 载具锁定解除
        ContainerDao containerDao = new ContainerDao()
                .setId(containerCode)
                .setIonLock(ConstantStatus.CONTAINER_NORMAL);
        containerService.updateDataById(containerDao);
    }

    /**
     * 载具库内+取货=开始入库库内储位
     *
     * @param outStoreId 库外储位id
     */
    public void inboundPickTask(String outStoreId, String containerCode) {
        // 修改目的储位状态
        StoreOutsideDao storeOutsideDao = new StoreOutsideDao()
                .setId(outStoreId)
                .setStatus(InboundStatusEnum.STORAGE_FREE.status);
        storeOutsideService.updateData(storeOutsideDao);

        // 载具锁定解除
        ContainerDao containerDao = new ContainerDao()
                .setId(containerCode)
                .setIonLock(ConstantStatus.CONTAINER_NORMAL);
        containerService.updateDataById(containerDao);

    }


    /**
     * 冻结出库
     *
     * @param containerCode 载具编码
     */
    public void freezeOutBoundTask(String containerCode) {
        FreezeDao freezeDao = freezeService.findDataByCode(containerCode);
        // 载具出库记录
        containerMoveService.createContainerMove(freezeDao.getFreezeName(), containerCode);

        // 冻结出库任务单信息状态
        freezeDao.setContainerStatus(ConstantStatus.CONTAINER_MERGE_ING);
        freezeService.updateDataByCode(freezeDao);

    }

    /**
     * 冻结回库
     *
     * @param containerCode 载具编码
     */
    public void freezeReturnTask(String containerCode) {
        // 冻结回库任务单信息状态
        List<MaterialDao> materialList = materialService
                .findDataDao(new MaterialDao().setContainerCode(containerCode));
        FreezeDao freezeDao = freezeService.findDataByCode(containerCode);
        List<FreezeTaskRecordDao> freezeRecordList = new ArrayList<>();
        for (MaterialDao materialDao : materialList) {
            FreezeTaskRecordDao freezeTaskRecordDao = new FreezeTaskRecordDao()
                    .setId(String.valueOf(SnowIdUtil.nextId()))
                    .setTaskId(freezeDao.getTaskId())
                    .setFloor(freezeDao.getFloor())
                    .setFreezeTime(new Timestamp(freezeDao.getFreezeTime().getTime()))
                    .setFreezeName(freezeDao.getFreezeName())
                    .setDisable(ConstantStatus.FREEZE)
                    .setFreezeDes(freezeDao.getFreezeDes())
                    .setFreezeNotes(freezeDao.getFreezeNotes());
            BeanUtil.copyProperties(materialDao, freezeTaskRecordDao, CopyOptions.create().setIgnoreNullValue(true));
            freezeRecordList.add(freezeTaskRecordDao);
        }
        freezeTaskRecordService.saveBatchData(freezeRecordList);
        // 同步黑湖冻结单信息
        ResponseResult<?> responseResult = MesNetworkRequest.materialFreezeRequest(containerCode, materialList);
        if (responseResult.getReturnCode() != 200) {
            throw new RuntimeException("同步MES冻结失败");
        }
    }

    /**
     * 合箱出库
     *
     * @param containerCode 载具编码
     */
    public void mergeOutBoundTask(String containerCode) {
//        // 修改合箱任务单信息状态
//        MergeTaskDao mergeTaskDao = new MergeTaskDao();
//        mergeTaskDao.setContainerCode(containerCode);
//        mergeTaskDao.setContainerStatus(ConstantStatus.CONTAINER_MERGE_ING);
//        mergeTaskService.updateData(mergeTaskDao);

        // 载具出库记录
        MergeTaskDao mergeTask = mergeTaskService.findByTaskByContainerCode(containerCode);
        containerMoveService.createContainerMove(mergeTask.getCreateName(), containerCode);
    }

    /**
     * 合箱回库
     */
    public void mergeReturnTask(String containerCode) {
        List<MaterialDao> materialList = materialService
                .findDataDao(new MaterialDao().setContainerCode(containerCode));
        // 冻结物料出库要解冻
        boolean flag = false;
        for (MaterialDao materialDao : materialList) {
            Integer disable = materialDao.getDisable();
            flag = disable != null && disable.equals(ConstantStatus.FREEZE);
        }
        if (flag) {
            // 冻结出库要解冻
            ResponseResult<?> responseResult = MesNetworkRequest.materialFreezeRequest(containerCode, materialList);
            if (responseResult.getReturnCode() != 200) {
                throw new RuntimeException("同步MES冻结失败");
            }
        }
    }

    /**
     * 盘点出库
     *
     * @param containerCode 载具编码
     */
    public void stockOutBoundTask(String containerCode) {
        inventoryTaskService.updateContainerStatusByCode(containerCode, ConstantStatus.CONTAINER_MERGE_ING);
        InventoryTaskDao inventoryTaskDao = inventoryTaskService.findInventoryTaskByContainerCode(containerCode);
        // 载具出库记录
        containerMoveService.createContainerMove(inventoryTaskDao.getCreateName(), containerCode);
    }

    /**
     * 盘点回库
     *
     * @param containerCode 载具编码
     */
    public void stockReturnTask(String containerCode) {

    }
}
